package com.pac.file.service.impl;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.MultipartPostMethod;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.common.tools.StringTools;
import com.common.tools.TimeTools;
import com.common.util.ErrorNumber;
import com.common.util.LogicException;
import com.common.util.PropertyUtils;
import com.pac.file.FileKeyContext;
import com.pac.file.bean.FileBean;
import com.pac.file.dao.FileDao;
import com.pac.file.service.FileService;

/**
 * 文件处理
 * 
 * @author chenlujun
 * @version [版本号, 2014年11月8日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@SuppressWarnings("deprecation")
@Service(value = "fileService")
public class FileServiceImpl implements FileService {
	private static Logger logger = Logger.getLogger(FileServiceImpl.class);

	@Autowired
	private FileDao fileDao;

	/**
	 * 文件传输到文件服务器
	 * 
	 * @param fileBean
	 *            需要上传的文件
	 * @return
	 * @see [类、类#方法、类#成员]
	 */
	private String transportFile(FileBean fileBean) {

		if (null == fileBean) {
			logger.error("文件上传出错，参数为空");
			throw new LogicException(ErrorNumber.PARAM_IS_NULL, "参数为空");
		}

		String originalName = fileBean.getName();
		String path = fileBean.getPath();
		File file = fileBean.getFile();
		if (null == file) {
			logger.error("文件上传失败，文件为空");
			throw new LogicException(ErrorNumber.PARAM_IS_NULL, "文件为空");
		}

		// 上传文件到文件服务
		String fileUpUrl = PropertyUtils.getValue("file.server.upload.url");
		MultipartPostMethod filePost = new MultipartPostMethod(fileUpUrl);
		HttpClient client = new HttpClient();
		try {
			filePost.addParameter("file", file);
		} catch (FileNotFoundException e) {
			logger.error("文件上传出错," + e);
			throw new LogicException(ErrorNumber.PARAM_IS_NULL, "未找到文件");
		}

		if (StringTools.isNull(originalName)) {
			originalName = file.getName();
		}

		// 设置上传文件的根目录
		String filePathRoot = PropertyUtils.getValue("file.server.path.root");
		path = filePathRoot + path;

		filePost.addParameter("fileName", originalName);
		filePost.addParameter("path", path);
		if(fileBean.isImgCompress())
		{
			filePost.addParameter("imgWidth", String.valueOf(fileBean.getImgWidth()));
			filePost.addParameter("imgHeight", String.valueOf(fileBean.getImgHeight()));
			filePost.addParameter("imgCompress", String.valueOf(fileBean.isImgCompress()));
		}
		// 由于要上传的文件可能比较大,因此在此设置最大的连接超时时间
		client.getHttpConnectionManager().getParams()
				.setConnectionTimeout(5000);
		// 文件上传到文件服务器的URL
		String filePath = "";
		try {
			int status = client.executeMethod(filePost);
			if (FileKeyContext.FILE_UPDATE_STATUS_SUCCESS == status) {
				filePath = filePost.getResponseBodyAsString();
			}
		} catch (HttpException e) {
			logger.error("上传文件出错，" + e);
			throw new LogicException(ErrorNumber.SYSTEM_ERROR, "连接文件服务器异常");
		} catch (IOException e) {
			logger.error("上传文件出错，" + e);
			throw new LogicException(ErrorNumber.SYSTEM_ERROR, "IO异常");
		}

		return filePath;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public FileBean uploadFile(File file, String originalName, String path)
			throws LogicException {

		if(originalName.indexOf(".")<0)
		{
			originalName+="originalName.jpg";
		}
		
		// 保存文件到文件服务器
		FileBean fileBean = new FileBean();
		fileBean.setFile(file);
		fileBean.setName(originalName);
		fileBean.setPath(path);
		String filePath = transportFile(fileBean);

		// 文件成功上传到文件服务器,保存文件信息到数据库
		if (!StringTools.isNull(filePath)) {
			String fileName = originalName;
			String fileType = fileName.substring(fileName.lastIndexOf('.') + 1);
			fileType = fileType.toUpperCase();
			String createDate = TimeTools.now();
			fileBean.setCreateDate(createDate);
			fileBean.setName(fileName);
			fileBean.setPath(filePath);
			String size = String.valueOf(file.length());
			fileBean.setSize(size);
			fileBean.setType(fileType);

			String fileId=fileDao.addFile(fileBean);
			fileBean.setId(fileId);
		}

		return fileBean;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean delFile(FileBean fileBean) throws LogicException {
		if (null == fileBean) {
			logger.error("删除文件出错，参数为空");
			throw new LogicException(ErrorNumber.PARAM_IS_NULL, "参数为空");
		}

		boolean reslut = false;

		// ID或者URL必须有一个不为空
		if (StringTools.isNull(fileBean.getId())
				&& StringTools.isNull(fileBean.getPath())) {
			logger.error("ID和文件URL都为空");
			throw new LogicException(ErrorNumber.PARAM_IS_NULL, "ID和路径都为空");
		}

		// 查询文件信息
		FileBean fileBeanR = findFile(fileBean);
		if (null != fileBeanR) {
			// 删除文件服务器上的文件
			HttpClient httpClient = new HttpClient();
			String filePath = fileBeanR.getPath();
			String fileDelUrl = PropertyUtils
					.getValue("file.server.delete.url");
			fileDelUrl += "?filePath=" + filePath;
			GetMethod getMethod = new GetMethod(fileDelUrl);

			int httpStatus = 0;
			try {
				httpStatus = httpClient.executeMethod(getMethod);
			} catch (HttpException e) {
				logger.error("删除文件出错，" + e);
				throw new LogicException(ErrorNumber.SYSTEM_ERROR, "请求文件服务器异常");
			} catch (IOException e) {
				logger.error("删除文件出错，" + e);
				throw new LogicException(ErrorNumber.SYSTEM_ERROR, "服务器内部错误");
			}

			// 文件服务器文件删除，删除数据库中记录
			if (FileKeyContext.FILE_UPDATE_STATUS_SUCCESS == httpStatus) {
				reslut = fileDao.delFileById(fileBean.getId());
			}
		}

		return reslut;
	}

	@Override
	public List<FileBean> queryFile(FileBean fileBean) {
		return fileDao.queryFile(fileBean);
	}

	@Override
	public FileBean findFile(FileBean fileBean) {

		List<FileBean> fileBeanList = fileDao.queryFile(fileBean);
		if (null != fileBeanList && fileBeanList.size() > 0) {
			return fileBeanList.get(0);
		}
		return null;
	}

	@Override
	public FileBean uploadMultipartFile(MultipartFile multipartFile,
			String filePath) {
		filePath += "/" + TimeTools.now("yyyy") + "/" + TimeTools.now("MM")
				+ "/" + TimeTools.now("dd");
		FileBean fileBean = new FileBean();
		if (multipartFile.isEmpty()) {
			logger.info("上传文件，文件未上传");
			return fileBean;
		} else {

			try {
				String tempDir = PropertyUtils.getValue("file.temp.dir");
				tempDir += "/" + StringTools.randomCode(32) + ".tmp";
				File upFile = new File(tempDir);
				multipartFile.transferTo(upFile);

				fileBean = uploadFile(upFile,
						multipartFile.getOriginalFilename(), filePath);
				// 删除临时文件
				upFile.delete();
			} catch (Exception e) {
				logger.error("上传文件出错，" + e.getMessage());
			}
		}

		return fileBean;
	}

	@Override
	public FileBean uploadFile(String url, String filePath) {
		FileBean fileBean = new FileBean();
		try {
			HttpClient client = new HttpClient();
			GetMethod get = new GetMethod(url);
			client.executeMethod(get);
			String tempDir = PropertyUtils.getValue("file.temp.dir");
			tempDir += "/" + StringTools.randomCode(32) + ".tmp";
			File storeFile = new File(tempDir);
			FileOutputStream output = new FileOutputStream(storeFile);
			output.write(get.getResponseBody());
			output.close();
			fileBean = uploadFile(storeFile, "weixin.jpg", filePath);
		} catch (Exception ex) {
			logger.error("文件地址：" + url);
			logger.error("从其他网站下载文件出错，" + ex);
		}

		return fileBean;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public FileBean uploadImg(File file, String originalName, String path,
			boolean imgCompress, int imgWidth, int imgHeight)
			throws LogicException {

		List<String> imgTypes = new ArrayList<String>();
		imgTypes.add("jpg");
		imgTypes.add("jpeg");
		imgTypes.add("png");
		imgTypes.add("gif");
		imgTypes.add("bmp");
		imgTypes.add("tif");
		imgTypes.add("tiff");
		
		String imgType = originalName.substring(originalName.lastIndexOf(".")+1,
				originalName.length());
		if (!imgTypes.contains(imgType.toLowerCase())) {
			logger.error("不支图片格式：" + imgType);
			throw new LogicException(ErrorNumber.LOGIC_EXCEPTION, "不支图片格式："
					+ imgType);
		}

		// 保存文件到文件服务器
		FileBean fileBean = new FileBean();
		fileBean.setFile(file);
		fileBean.setName(originalName);
		fileBean.setPath(path);
		fileBean.setImgCompress(imgCompress);
		fileBean.setImgWidth(imgWidth);
		fileBean.setImgHeight(imgHeight);
		String filePath = transportFile(fileBean);

		// 文件成功上传到文件服务器,保存文件信息到数据库
		if (!StringTools.isNull(filePath)) {
			String fileName = originalName;
			String fileType = fileName.substring(fileName.lastIndexOf('.') + 1);
			fileType = fileType.toUpperCase();
			String createDate = TimeTools.now();
			fileBean.setCreateDate(createDate);
			fileBean.setName(fileName);
			fileBean.setPath(filePath);
			String size = String.valueOf(file.length());
			fileBean.setSize(size);
			fileBean.setType(fileType);

			fileDao.addFile(fileBean);
		}

		return fileBean;
	}

}
